package omega

import (
	"bytes"
	"encoding/gob"
	"reflect"

	"github.com/pkg/errors"
)

type Encode interface {
	Marshal([]reflect.Value) ([]byte, error)
	Unmarshal([]byte) ([]reflect.Value, error)
}

type gobEncode struct{}

func (s *gobEncode) Unmarshal(payloads []byte) ([]reflect.Value, error) {
	b := bytes.NewReader(payloads)
	dec := gob.NewDecoder(b)
	args := make([]interface{}, 0)
	err := dec.Decode(&args)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	values := make([]reflect.Value, 0)
	for _, arg := range args {
		values = append(values, reflect.ValueOf(arg))
	}
	return values, nil
}

func (s *gobEncode) Marshal(values []reflect.Value) ([]byte, error) {
	var b bytes.Buffer
	enc := gob.NewEncoder(&b)
	args := make([]interface{}, 0)
	for _, value := range values {
		args = append(args, value.Interface())
	}
	err := enc.Encode(args)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return b.Bytes(), nil
}
